package db

import (
	"encoding/json"

	"github.com/samber/oops"
	bolt "go.etcd.io/bbolt"

	"github.com/aquasecurity/trivy-db/pkg/types"
)

const (
	vulnerabilityDetailBucket = "vulnerability-detail"
)

func (dbc Config) PutVulnerabilityDetail(tx *bolt.Tx, cveID string, source types.SourceID, vuln types.VulnerabilityDetail) error {
	if err := dbc.put(tx, []string{vulnerabilityDetailBucket, cveID}, string(source), vuln); err != nil {
		return oops.With("vuln_id", cveID).With("source_id", source).Wrapf(err, "failed to put vulnerability detail")
	}
	return nil
}

func (dbc Config) GetVulnerabilityDetail(cveID string) (map[types.SourceID]types.VulnerabilityDetail, error) {
	eb := oops.With("vuln_id", cveID)
	values, err := dbc.forEach([]string{vulnerabilityDetailBucket, cveID})
	if err != nil {
		return nil, eb.Wrapf(err, "unable to get vulnerability detail")
	}
	if len(values) == 0 {
		return nil, nil
	}

	vulns := map[types.SourceID]types.VulnerabilityDetail{}
	for source, value := range values {
		var vuln types.VulnerabilityDetail
		if err = json.Unmarshal(value.Content, &vuln); err != nil {
			return nil, eb.Wrapf(err, "json unmarshal error")
		}
		vulns[types.SourceID(source)] = vuln
	}
	return vulns, nil
}

func (dbc Config) DeleteVulnerabilityDetailBucket() error {
	return dbc.deleteBucket(vulnerabilityDetailBucket)
}
